package dao

import (
	"context"
	"database/sql"
	"sale-admin/internal/dal"
	"strings"

	"github.com/golang-module/carbon/v2"
	"gorm.io/gorm"
)

type OrderRefund struct{}

// 退款金额及退款笔数
func (OrderRefund) OrderRefundList(ctx context.Context, db *gorm.DB, robotName, date string) (result []RefundStruct, err error) {
	r := dal.Use(db).MaOrderRefund
	tx := r.WithContext(ctx)
	if date != "" {
		start := carbon.ParseByLayout(date, carbon.DateLayout).ToStdTime()
		end := carbon.ParseByLayout(date+" 23:59:59", carbon.DateTimeLayout).ToStdTime()
		tx = tx.Where(r.AddTime.Between(start, end))
	}
	if robotName != "" {
		tx = tx.Where(r.RobotName.In(strings.Split(robotName, ",")...))
	}
	tx.Select(r.RobotName,
		r.OutTradeNo,
		r.ID.Count().As("refund_order_count"),
		r.RefundPaymentAmount.Sum().As("refund_order_amount"),
	)
	if robotName != "" {
		tx = tx.Group(r.RobotName)
	} else {
		tx = tx.Group(r.OutTradeNo)
	}
	tx.Scan(&result)
	return
}

// 通过商品筛选订单退款列表【按机器+订单号分组】
func (OrderRefund) OrderRefundListByGoods(ctx context.Context, db *gorm.DB, goodsID string, date string) (result []RefundStruct, err error) {
	r := dal.Use(db).MaOrderRefund
	o := dal.Use(db).MaOrder
	tx := r.WithContext(ctx)
	if date == "" && goodsID == "" {
		return
	}

	start := carbon.ParseByLayout(date, carbon.DateLayout).ToStdTime()
	end := carbon.ParseByLayout(date+" 23:59:59", carbon.DateTimeLayout).ToStdTime()
	tx = tx.Where(r.AddTime.Between(start, end))

	if goodsID != "" {
		var orderIDs []sql.NullString
		threeDaysStart := carbon.FromStdTime(start).SubDays(3)
		o.WithContext(ctx).
			Where(o.GoodsID.Eq(goodsID)).
			Where(o.AddTime.Between(threeDaysStart.ToStdTime(), end)).
			Pluck(o.EndOutTradeNo, &orderIDs) // 用 end_out_trade_no 因为退款表的out_trade_no和订单表的end_out_trade_no一样会带后缀
		// end_out_trade_no 有null,需处理
		var newOrderIDs []string
		for _, v := range orderIDs {
			if v.Valid {
				newOrderIDs = append(newOrderIDs, v.String)
			}
		}
		if len(newOrderIDs) == 0 {
			return
		}
		tx = tx.Where(r.OutTradeNo.In(newOrderIDs...))
	}
	tx.Select(r.RobotName,
		r.OutTradeNo,
		r.ID.Count().As("refund_order_count"),
		r.RefundPaymentAmount.Sum().As("refund_order_amount"),
	).Group(r.RobotName, r.OutTradeNo).
		Scan(&result)
	return
}
